<template>
  <div
    class="box"
    ref="dateBox"
    @click="dateBoxClick($event)"
    :style="{
      width: type === 'week' ? '280px' : '248px',
      display: dateBoxStyle
    }"
  >
    <div>
      <input type="text" class="input-box" v-model="selectValue" />
    </div>
    <div class="d-flex justify-content-between" style="padding: 5px 0px">
      <div>
        <img src="./assets/left.png" class="next-btn" @click.stop="lastClick" />
      </div>
      <div>
        <select style="width: 80px; margin-right: 5px" v-model="selectMonth" v-show="type !== 'month'">
          <option v-for="item in monthList" :key="item.id" :value="item.value" :disabled="item.disable">
            {{ item.text }}
          </option>
        </select>
        <select style="width: 70px" v-model="selectYear">
          <option :value="item" v-for="item in yearList" :key="'year' + item">
            {{ item }}
          </option>
        </select>
      </div>
      <div>
        <img src="./assets/right.png" class="next-btn" @click.stop="nextClick" />
      </div>
    </div>
    <dayComponent
      v-if="type === 'day'"
      :yearMonth="localYearMonth"
      :month="selectMonth"
      :start="start"
      :min="props.min"
      :max="props.max"
      v-model:value="selectValue"
    />
    <weekComponent
      v-if="type === 'week'"
      :yearMonth="localYearMonth"
      :month="selectMonth"
      :thisYearStart="thisYearStart"
      :lastYearStart="lastYearStart"
      :nextYearStart="nextYearStart"
      :min="props.min"
      :max="props.max"
      :weekInfo="props.weekInfo"
      v-model:value="selectValue"
    />
    <monthComponent
      v-if="type === 'month'"
      :year="selectYear"
      :monthList="month"
      :min="props.min"
      :max="props.max"
      v-model:value="selectValue"
    />
  </div>
</template>
<script>
import monthComponent from './components/month.vue';
import dayComponent from './components/day.vue';
import weekComponent from './components/week.vue';
export default {
  name: 'my-date',
  components: {
    monthComponent,
    dayComponent,
    weekComponent
  }
};
</script>
<script setup>
import { computed, reactive, ref, toRefs } from '@vue/reactivity';
import { watch } from 'vue';
const moment = window.moment;
//eslint-disable-next-line
const props = defineProps({
  type: String,
  min: String,
  max: String,
  weekInfo: Object,
  value: String,
  visible: Boolean
});
//eslint-disable-next-line
const emits = defineEmits(['update:value', 'update:visible']);
const { value, type, visible } = toRefs(props);
const dateBox = ref();
//初始化当前月份
let selectMonth = ref(''); //当前显示月
let selectYear = ref(''); //当前显示年
let selectValue = ref(''); //当前选择值：月-表示月、日-表示日期、周-表示周别
// 监听数据，用于是否日期插件
let start = computed(() => {
  return props.weekInfo[selectYear.value];
});
let lastYearStart = computed(() => {
  return props.weekInfo[+selectYear.value - 1];
});
let nextYearStart = computed(() => {
  return props.weekInfo[+selectYear.value + 1];
});
const thisYearStart = computed(() => {
  return props.weekInfo[+selectYear.value];
});
watch(
  [value, type],
  (oldVal, newVal) => {
    if (oldVal.toString() !== newVal.toString() && newVal[1] !== selectValue.value) {
      //TODO
      if (props.type === 'week') {
        selectYear.value = moment(props.value, 'YYYYWW').get('year');
        selectMonth.value =
          moment(start.value, 'YYYYMMDD')
            .add(+props.value.substring(4) * 7, 'days')
            .get('month') + 1;
        selectValue.value = props.value;
      } else {
        selectYear.value = moment(props.value, 'YYYYMM').get('year');
        selectMonth.value = moment(props.value, 'YYYYMM').get('month') + 1;
        selectValue.value = props.value;
      }
    }
  },
  { immediate: true }
);
watch(selectValue, () => {
  emits('update:value', selectValue.value);
  emits('update:visible', false);
});
watch(selectYear, () => {
  //年代发生变化时，检查月份是否在范围内
  if (!monthList.value.filter((item) => item.value === selectMonth.value).length === 0) {
    selectMonth.value = monthList.value[0].value;
  }
});
//年范围
const yearList = computed(() => {
  let startYear = moment(props.min, 'YYYYMMDD').get('year') ?? 0;
  let endYear = moment(props.max, 'YYYYMMDD')?.get('year') ?? 0;
  let result = [];
  while (startYear <= endYear) {
    result.push(startYear);
    startYear++;
  }
  return result;
});
//当前插件中选择通过dom选择的年月
let localYearMonth = computed(() => {
  return `${selectYear.value}${selectMonth.value.toString().padStart(2, '0')}`;
});

const month = reactive(['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']);

let monthList = computed(() => {
  const result = [];
  let minMoment = moment(props.min, 'YYYYMMDD');
  let maxMoment = moment(props.max, 'YYYYMMDD');
  for (let index in month) {
    let value = +index + 1;
    let disableFlag = false;
    let nowYearMonth = `${selectYear.value}${value.toString().padStart(2, '0')}`;
    if (
      (yearList.value.indexOf(selectYear.value) === 0 ||
        yearList.value.indexOf(selectYear.value) === yearList.value.length - 1) &&
      (+nowYearMonth < +minMoment.format('YYYYMM') || +nowYearMonth > +maxMoment.format('YYYYMM'))
    ) {
      disableFlag = true;
    }
    if (!disableFlag) {
      result.push({
        id: nowYearMonth,
        value,
        disable: disableFlag,
        text: month[index]
      });
    }
  }
  return result;
});

const lastClick = function () {
  if (props.type !== 'month') {
    let local = `${selectYear.value}${selectMonth.value.toString().padStart(2, '0')}`;
    let minMoment = moment(props.min, 'YYYYMMDD').format('YYYYMM');
    if (+local <= +minMoment) {
      return;
    }
    if (selectMonth.value === 1) {
      let lastYear = selectYear.value - 1;
      if (!yearList.value.includes(lastYear)) {
        return;
      }
      selectMonth.value = 12;
      selectYear.value = selectYear.value - 1;
    } else {
      selectMonth.value = selectMonth.value - 1;
    }
  } else {
    if (!yearList.value.includes(selectYear.value - 1)) {
      return;
    }
    selectYear.value -= 1;
  }
};
const nextClick = function () {
  if (props.type !== 'month') {
    let local = `${selectYear.value}${selectMonth.value.toString().padStart(2, '0')}`;
    let maxMoment = moment(props.max, 'YYYYMMDD').format('YYYYMM');
    if (+local >= +maxMoment) {
      return;
    }
    if (selectMonth.value === 12) {
      let nextYear = selectYear.value + 1;
      if (!yearList.value.includes(nextYear)) {
        return;
      }
      selectMonth.value = 1;
      selectYear.value = +selectYear.value + 1;
    } else {
      selectMonth.value = +selectMonth.value + 1;
    }
  } else {
    if (!yearList.value.includes(selectYear.value + 1)) {
      return;
    }
    selectYear.value += 1;
  }
};
const dateBoxStyle = computed(() => {
  console.log(visible.value);
  if (visible.value) {
    return 'block';
  } else {
    return 'none';
  }
});
const dateBoxClick = (event) => {
  event.stopPropagation();
};
</script>
<style lang="scss" scoped>
.box {
  min-height: 190px;
  width: 248px;
  border-radius: 4px;
  box-shadow: 0px 0px 5px 5px #eeeeee;
  padding: 12px;
  position: absolute;
  margin-top: 4px;
  display: none;
}
.input-box {
  height: 30px;
  width: 100%;
  background: url(./assets/calendar.png) no-repeat;
  background-size: 20px 20px;
  background-position-y: 3px;
  padding-left: 25px;
  padding-right: 25px;
  border-radius: 4px;
}
.next-btn {
  height: 20px;
  width: 20px;
  cursor: pointer;
}
.next-btn:hover {
  background: #eeeeee;
}
</style>
